原文来自于http://dave.cheney.net/201311/15/evaluation-order-oddity

  先来看这段代码

package main

import "fmt"

type T struct {
        i int
}

func (t *T) readInt() int {
        t.i += 4
        return 42
}

func main() {
        var d = T{i: 200}
        end := d.i - 4 + d.readInt()
        fmt.Println(end)
}

  根据Gospec我们可知表达式的求值过程是自左向右的。所以我们可以想想这段代码打印出来的应该是

200-4 + 42 = 238

  但是238是正确答案么?

% go run odd.go 
242

  啊,太奇怪了,然后让我们来看看gccgo的结果

% go run -compiler gccgo odd.go 
238

 &esmp;看来它得到了正确答案,那么是gc有问题了或者这个表达式的求值方式确实是相反的?

  事实上这两个编译器都是正确的,因为这个表达式的求值顺序是不确定的。

  如果想要得到你想要的答案,应该把这个表达式分成两行,消除加d.i时的二义性。

func main() {
        var d = T{i:200}
        v := int(d.readInt32())
        end := v + d.i - 4
        fmt.Println(end)    // prints         242
}


blog comments powered by Disqus

Published

2013-11-15

Categories


Tags